Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error when giving an array as parameter to an endpoint body request #1037

Merged

Conversation

thomasphansen
Copy link
Contributor

…equest

PR checklist

  • Read the contribution guidelines.
  • Ran the shell script under ./bin/ to update Petstore sample so that CIs can verify the change. (For instance, only need to run ./bin/{LANG}-petstore.sh and ./bin/security/{LANG}-petstore.sh if updating the {LANG} (e.g. php, ruby, python, etc) code generator or {LANG} client's mustache templates). Windows batch files can be found in .\bin\windows\.
  • Filed the PR against the correct branch: master, 3.3.x, 4.0.x. Default: master.
  • Copied the technical committee to review the pull request if your PR is targeting a particular programming language.
  • @jebentier
  • @dkarlovi
  • @mandrean
  • @jfastnacht
  • @ackintosh
  • @ybelenko

Description of the PR

This PR targets Issue #1036 : as of today, it is not possible to provide an array of model objects as parameter for an operation, since it will not be properly json-encoded. This PR fixes this, by adding a recursive method that is able to properly json-encode arrays of model objects.

if($headers['Content-Type'] !== 'application/json') {
$httpBody = $_tempBody;
} else {
$httpBody = $this->formatBody($_tempBody);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@thomasphansen thanks for the PR. What about using ObjectSerializer::sanitizeForSerialization instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, makes sense! :D

@thomasphansen
Copy link
Contributor Author

(BTW, I just found this very nice article on how to contribute to openapi-generator: https://medium.com/ringcentral-developers/openapi-generator-for-go-contribution-quickstart-8cc72bf37b53
Maybe it could be a nice thing to have link for it in CONTRIBUTING.md? :) )

@thomasphansen
Copy link
Contributor Author

thomasphansen commented Sep 17, 2018

So: Travis is failing because the ObjectSerializer::sanitizeForSerialization() method deals poorly with \stdClass objects. I can see some possible solutions here:

  1. Adjust ObjectSerializer::sanitizeForSerialization() to deal with \stdClass. This could be done by either:
    a. ignoring \stdClass objects (and just return them untouched); or
    b. (probably the right thing to do):
   (...)
   } elseif (is_object($data)) {
       if ($data instanceOf ModelInterface) {
           // Current code for dealing with objects
       } else {
           //  for each property inside the object, run sanitizeForSerialization() on its value (just like it's currently done for all objects, but without using the OpenAPI-specific methods)
       }
   }
  1. test for \stdClass objects before calling sanitizeForSerialization()

What do you think @wing328 ? :)

@thomasphansen
Copy link
Contributor Author

Pushed a commit implementing 1.b option... :)

@thomasphansen
Copy link
Contributor Author

Well, I'm not being able to get travis-ci finishing the tests: I'm getting the message "
The job exceeded the maximum time limit for jobs, and has been terminated.". I don't think there is anything I can do to fix it. I've tested this solution, and manually run all the phpunit tests under samples/client/petstore/php/OpenAPIClient-php/tests. What else can I do? :)

@wing328
Copy link
Member

wing328 commented Sep 18, 2018

@thomasphansen I've restarted the job and all tests pass.

cc @jebentier @dkarlovi @mandrean @jfastnacht @ackintosh @ybelenko

Copy link
Contributor

@ackintosh ackintosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for this PR!

&& !in_array($value, $openAPIType::getAllowableEnumValues(), true)) {
$imploded = implode("', '", $openAPIType::getAllowableEnumValues());
throw new \InvalidArgumentException("Invalid value for enum '$openAPIType', must be one of: '$imploded'");
if($data instanceof ModelInterface) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: please put a space after if.

// \stdClass has no __toString(), so we should encode it manually
if ($httpBody instanceof \stdClass && $headers['Content-Type'] === 'application/json') {
$httpBody = \GuzzleHttp\json_encode($httpBody);
if($headers['Content-Type'] !== 'application/json') {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: please put a space after if.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about invert the if condition like below:

if ($headers['Content-Type'] !== 'application/json') {
    $httpBody = $_tempBody;
} else {
    $httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization($_tempBody));
}

↓↓↓

if ($headers['Content-Type'] === 'application/json') {
    $httpBody = \GuzzleHttp\json_encode(ObjectSerializer::sanitizeForSerialization($_tempBody));
} else {
    $httpBody = $_tempBody;
}

The === in if statement may be Intuitive and readable. 💡

@ackintosh
Copy link
Contributor

I've restarted the travis-ci build as it was resulted in the error.

[ERROR] Failed to execute goalorg.fortasoft:gradle-maven-plugin:1.0.8:invoke(default) on projectopenapi-generator-gradle-plugin-mvn-wrapper:org.gradle.tooling.GradleConnectionException: Could not execute build using Gradle distribution 'https://services.gradle.org/distributions/gradle-4.10-rc-1-bin.zip'. ->[Help 1]

Copy link
Contributor

@ackintosh ackintosh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the update. Looks good to me. ✨

@ackintosh ackintosh merged commit ca9a4a2 into OpenAPITools:master Sep 19, 2018
@thomasphansen thomasphansen deleted the th_fix_php_array_parameter branch September 19, 2018 12:27
jaumard pushed a commit to jaumard/openapi-generator that referenced this pull request Sep 21, 2018
OpenAPITools#1037)

* PR: Fix error when giving an array as parameter to an endpoint body request

* PR OpenAPITools#1037 - Fix issue with array as parameter to operation

* update samples

* PHP - ObjectSerializer::sanitizeForSerialization(): manage \stdClass objects properly

* update samples

* bug fix: missing "use" clause

* update samples

* Changes after @ackintosh review

* update samples
@wing328 wing328 changed the title PR: Fix error when giving an array as parameter to an endpoint body r… Fix error when giving an array as parameter to an endpoint body request Oct 1, 2018
@wing328
Copy link
Member

wing328 commented Oct 2, 2018

@thomasphansen thanks again for the PR, which is included in the v3.3.0 minor release: https://twitter.com/oas_generator/status/1046941449609068544

A-Joshi pushed a commit to ihsmarkitoss/openapi-generator that referenced this pull request Feb 27, 2019
OpenAPITools#1037)

* PR: Fix error when giving an array as parameter to an endpoint body request

* PR OpenAPITools#1037 - Fix issue with array as parameter to operation

* update samples

* PHP - ObjectSerializer::sanitizeForSerialization(): manage \stdClass objects properly

* update samples

* bug fix: missing "use" clause

* update samples

* Changes after @ackintosh review

* update samples
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants